package com.sqsf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Controller//交由spring容器管理
public class MyController {

    //spring通过组件扫描 读取配置url与方法之间的映射关系
    @RequestMapping("/a")
    public void a() {
        System.out.println("MyController-a方法执行");
    }

    @RequestMapping("/b")
    public void b() {
        System.out.println("MyController-b方法执行");
    }

    @RequestMapping("/c")
    public void c() {
        System.out.println("MyController-c方法执行");
    }


    //RequestMapping注解可以通过 method属性限制请求url的方式
    //默认任意请求方式都可以执行
    @RequestMapping(value = "/d", method = RequestMethod.POST)
    public void d() {
        System.out.println("MyController-d方法执行");
    }


    //还可以限制请求时携带的参数
    //请求当前url时必须携带name为username的数据
    @RequestMapping(value = "/e", params = {"username"})
    public void e() {
        System.out.println("MyController-e方法执行");
    }

    //请求当前url如果拥有username属性 那么值不允许为admin
    @RequestMapping(value = "/f", params = {"username!=admin"})
    public void f() {
        System.out.println("MyController-f方法执行");
    }

    //SpringMVC请求数据的获取
    //在实际的开发中 我们需要基于前端请求的url与之携带的数据
    //完成对应功能 所以在springMVC中 我们需要获取请求携带的数据

    //SpringMVC请求数据的获取-servlet原始方式
    //实现的流程为 调用请求对象的方法 填入需要获取数据的name 获取对应数据
    //因为所有数据在web中进行传输使用二进制字符串的形式
    //所以获取的数据类型为字符串 需要我们在使用前进行类型转换
    @RequestMapping("/req1")
    @ResponseBody
    public void req1(HttpServletRequest request) {
        String name = request.getParameter("name");
        String ageStr = request.getParameter("age");
        int age = Integer.valueOf(ageStr);
        System.out.println(name + "|" + age);
    }

    //SpringMVC请求数据的获取-常用类型数据的获取
    //SpringMVC基于servlet对应的方法与上面实现获取数据的流程
    //为我们提供了更加简单便捷的获取数据的方式
    //SpringMVC会自动从请求中 基于当前方法的参数列表进行数据的获取
    //获取完数据后 进行类型匹配 如果参数类型是字符串 直接赋值给变量
    //如果类型不匹配 SpringMVC内置了简单的类型处理器(String=>int) 会进行转换后赋值
    @RequestMapping("/req2")
    @ResponseBody
    public void req2(String name, int age) {
        System.out.println(name + "|" + age);
    }

    //有时候为了安全性 不暴露属性名 前端请求携带的数据name不会直接匹配
    //这个时候就需要使用参数绑定注解 进行参数绑定实现数据的获取
    //使用参数绑定会回实现与RequestMapping注解相似的功能
    //要求请求时必须携带指定name的数据 因为RequestParam注解中 有一个属性 默认为true
    //如果不想限制请求时必须携带  那么可以将其设置为false
    @RequestMapping("/req3")
    @ResponseBody
    public void req3(@RequestParam(value = "uname", required = false) String name, int age) {
        System.out.println(name + "|" + age);
    }

    //有时后我们需要实现这样一个需求
    //如果携带了对应数据 使用对应数据赋值 如果没有使用默认值赋值
    //额外配置defaultValue属性进行默认值配置
    @RequestMapping("/req4")
    @ResponseBody
    public void req4(String name, @RequestParam(value = "age", required = false, defaultValue = "18") int age) {
        System.out.println(name + "|" + age);
    }

    //SpringMVC请求数据的获取-自定义类型数据的获取
    //后端数据基于ORM对象关系映射 前端在实现注册时 需要发送大量的数据
    //可以使用如上方式依次接收 但是我们发现 这些数据都是基于某个对象的属性
    //这个时候SpringMVC就提供了自动注入属性的功能
    //与之前获取流程一样 先根据对象的属性获取对应的数据 然后调用对应的setter方法
    //将获取的数据注入到对象中
    @RequestMapping("/req5")
    @ResponseBody
    public void req4(User user) {
        System.out.println(user);
    }

    //SpringMVC请求数据的获取-数组类型数据的获取
    //在实际开发中 实现批量删除功能时 前端会使用复选框传递多个name相同的数据
    //还是调用请求对象的方法 将数据以数组的形式接收
    @RequestMapping("/req6")
    @ResponseBody
    public void req6(HttpServletRequest request) {
        String[] ids = request.getParameterValues("id");
        System.out.println(Arrays.toString(ids));
    }

    //SpringMVC会根据请求的参数类型 决定对应方法的调用
    @RequestMapping("/req7")
    @ResponseBody
    public void req7(int[] id) {
        System.out.println(Arrays.toString(id));
    }

    //SpringMVC请求数据的获取-json字符串类型数据的获取
    //基于前后台分离项目 前台发送请求携带的数据 就不是之前的简单类型
    //而是通过json的形式进行数据的发送 SpringMVC不止需要获取数据 还需要对json字符串进行解析

    //获取json对象数据
    //使用java对象 接受json格式的对象数据
    //json数据是在请求体中以字符串的形式进行发送 需要获取解析后才能存入数据
    //使用RequestBody注解告诉SpringMVC这是一个需要解析的json格式数据
    @RequestMapping("/req8")
    @ResponseBody
    public void req8(@RequestBody User user) {
        System.out.println(user);
    }

    //获取json数组数据
    //一般不会 但是有些功能可能导致前台向后台发送大量数据
    @RequestMapping("/req9")
    @ResponseBody
    public void req9(@RequestBody List<User> userList) {
        System.out.println(userList);
    }
}
